package com.xnx3.j2ee.system;


import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import com.xnx3.BaseVO;
import com.xnx3.j2ee.util.ConsoleUtil;

/**
 * 重写500错误，变为返回http 200状态码，返回 {"result": 0,"info": "处理异常，请稍后再试"}
 * @author 管雷鸣
 */
@Configuration
public class ErrorConfiguration {

	@Bean
	public ErrorPageController basicErrorController(ErrorAttributes errorAttributes, 
			ServerProperties serverProperties, 
			ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
		return new ErrorPageController(errorAttributes, serverProperties.getError(), 
				errorViewResolversProvider.getIfAvailable());
	}
	
}

class ErrorPageController extends BasicErrorController {

	public ErrorPageController(ErrorAttributes errorAttributes, ErrorProperties errorProperties,
			List<ErrorViewResolver> errorViewResolvers) {
		super(errorAttributes, errorProperties, errorViewResolvers);
	}

	@Override
	protected Map<String, Object> getErrorAttributes(HttpServletRequest request, ErrorAttributeOptions options) {
		Map<String, Object> map = super.getErrorAttributes(request, options);
		StringBuffer sb = new StringBuffer();
		sb.append("-------- ERROR START-------");
//		if(map.get("timestamp") != null) {
//			error = "timestamp:"+map.get("timestamp").toString();
//		}
//		if(map.get("path") != null) {
//			if(error.length() > 0) {
//				error = error + "\n";
//			}
//			error = error + "path:"+map.get("path").toString();
//		}
//		if(map.get("trace") != null) {
//			if(error.length() > 0) {
//				error = error + "\n";
//			}
//			error = error + map.get("trace").toString();
//		}
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			if(entry.getValue() != null) {
				sb.append("\n"+entry.getKey()+" : "+entry.getValue().toString());
			}
		}
		sb.append("\nmethod : "+request.getMethod());
		sb.append("\nreferer : "+request.getHeader("referer"));
		
		if(request.getParameterMap().size() > 0) {
			sb.append("\nrequest params:");
		}
		for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
			String value = "";
			for (int i = 0; i < entry.getValue().length; i++) {
				if(value.length() > 0) {
					value = value + " , ";
				}
				value = value + entry.getValue()[i];
			}
			if(value.length() > 100000) {
				value = "... The content is too long, exceeding 100000 characters, omitted";
			}
			sb.append("\n\t"+entry.getKey()+" : "+value);
		}
		sb.append("\n-------- ERROR END-------");
		ConsoleUtil.error(sb.toString());
		
		map.put("result", BaseVO.FAILURE);
		map.put("info", "处理异常，请稍后再试");
		String status = "";
		if(map.get("status") != null) {
			status = map.get("status").toString();
		}
		if(status.equals("400")) {
			//400出错，那可能是传入参数出现了错误
			map.put("info", "传入参数异常，请检查是否有必填项未传入，或传入的某个参数的类型不符");
		}
		
		map.remove("trace");
		map.remove("timestamp");
		map.remove("path");
		map.remove("status");
		return map;
	}

	@Override
	protected HttpStatus getStatus(HttpServletRequest request) {
		// TODO Auto-generated method stub
		HttpStatus httpStatus = super.getStatus(request);
		if(httpStatus.is5xxServerError()) {
			//因为500错误都有上面的接口捕捉返回了，所以这里将500响应直接变成200响应，错误信息就在 info 中了
			return HttpStatus.OK;
		}else {
			return httpStatus;
		}
	}
	
}
 